<?php
class SearchService
{
	private $snoopy 	= NULL;
	
	private $selApi		= -1;
	
	private $selRndApi	= true;
	
	/**
	 * 实例化Snoopy
	 */
	public function instanceSnoopy()
	{
		if ($this->snoopy == NULL)
		{
			$this->snoopy = new Snoopy();
		}
	}
	
	/**
	 * 生成签名
	 * @param $paramArr：api参数数组
	 * @return $sign
	 */
	public function createSign($paramArr)
	{
		$apiSetting		= C('SettingService')->get('api_setting',true);
		$secret			= $apiSetting['taobao_api_appsecret'];
		$secrets	= explode(',', $secret);
		$secret		= $secrets[$this->selApi];
		$sign		= '';
		ksort($paramArr);
		foreach ($paramArr as $key => $val)
		{
			if ($key !=='' && $val !=='')
			{
				$sign .= $key.$val;
			}
		}
		$sign = strtoupper(md5($secret.$sign.$secret));
		return $sign;
	}
	
	/**
	 * 生成字符串参数 
	 * @param $paramArr：api参数数组
	 * @return $strParam
	 */
	public function createStrParam ($paramArr)
	{
		$strParam = '';
		foreach ($paramArr as $key => $val)
		{
			if ($key !== '' && $val !=='')
			{
				$strParam .= $key.'='.urlencode($val).'&';
			}
		}
		return $strParam;
	}
	
	/**
	 * 以GET方式访问api服务
	 * @param $paramArr：api参数数组
	 * @return $result
	 */
	public function getResult($paramArr)
	{
		$this->instanceSnoopy();
		$paramArr	= $this->addDefaultParameters($paramArr);
		$sign 		= $this->createSign($paramArr);
		$strParam	 = $this->createStrParam($paramArr);
		$strParam 	.= 'sign='.$sign;
		
		$format	= '';
		$apiSetting		= C('SettingService')->get('api_setting',true);
		if($paramArr['pisces'])
		{
			$this->snoopy->fetch($apiSetting['pisces_api_url'].'&'.$strParam);
			$result 	= $this->snoopy->results;
			$format		= 'json';
		}
		else
		{
			$this->snoopy->fetch($apiSetting['taobao_api_url'].'?'.$strParam);
			$result 	= $this->snoopy->results;
			if($apiSetting['format']=='json')
			{
				$result		= str_replace("\n",'\n',$result);
			}
		}
		
		return $this->getArrayData($result,$format);
	}
	
	/**
	 * 以POST方式访问api服务
	 * @param $paramArr：api参数数组
	 * @return $result
	 */
	public function postResult($paramArr)
	{
		$this->instanceSnoopy();
		$paramArr			= $this->addDefaultParameters($paramArr);
		$sign 				= $this->createSign($paramArr);
		$paramArr['sign'] 	= $sign;
		
		$apiSetting		= C('SettingService')->get('api_setting',true);
		$this->snoopy->submit($apiSetting['taobao_api_url'], $paramArr);
		$result 			= $this->snoopy->results;
		
		return $result;
	}
	
	/**
	 * 以POST方式访问api服务，带图片
	 * @param $paramArr：api参数数组
	 * @param $imageArr：图片的服务器端地址，如array('image' => '/tmp/cs.jpg')形式
	 * @return $result
	 */
	public function postImageResult($paramArr, $imageArr)
	{
		$this->instanceSnoopy();
		
		$paramArr			= $this->addDefaultParameters($paramArr);
		$sign 				= $this->createSign($paramArr);
		$paramArr['sign'] 	= $sign;
		
		$apiSetting		= C('SettingService')->get('api_setting',true);
		$this->snoopy->_submit_type = "multipart/form-data";
		$this->snoopy->submit($apiSetting['taobao_api_url'], $paramArr, $imageArr);
		return $this->snoopy->results;
	}
	
	
	private function addDefaultParameters($arr)
	{
		$apiSetting		= C('SettingService')->get('api_setting',true);
		$apiKey			= $apiSetting['taobao_api_appkey'];
		$keys			= explode(',', $apiKey);
		$this->getSelApi($keys);
		$apiKey			= $keys[$this->selApi];
		$tmp			= array('api_key'=>$apiKey,'format'=>$apiSetting['format'],'v' => '2.0','sign_method'=>'md5','timestamp'=>date('Y-m-d H:i:s'));
		foreach($arr as $k=>$v)
		{
			$tmp[$k]	= $v;
		}
		
		return $tmp;
	}
	
	private function getSelApi($keys)
	{
		//使用指定的api，不随机选择
		if($this->selRndApi===false)
		{
			if($this->selApi<=0)
			{
				$this->selApi	= 0;
			}
			return;
		}
		
		//随机选择api
		$num	= count($keys);
		if($num>1)
		{
			$selApi			= $this->selApi;
			$try			= 0;
			while($this->selApi==$selApi && $try<100)
			{
				$selApi		= rand(0,$num-1);
				$try++;
			}
			$this->selApi	= $selApi;
		}
		else
		{
			$this->selApi	= 0;
		}
	}
	
	public function setSelApi($selApi)
	{
		$this->selApi	= $selApi;
	}
	
	public function setSelectRandApi($v)
	{
		$this->selRndApi	= $v;
	}
	
	private function getArrayData($data,$format='')
	{
		if($format=='')
		{
			$apiSetting		= C('SettingService')->get('api_setting',true);
			$format			= $apiSetting['format'];
		}
		
		if($format=='xml')
		{
			$nodeName	= substr($data,strpos($data,'?><')+3,100);
			$nodeName	= substr($nodeName,0,strpos($nodeName,'>'));
			$xml	= simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
			$tmp 	= $this->object2array($xml);
			$ret[$nodeName]	= $tmp;
		}
		else
		{
			$ret	= json_decode($data,true);
		}
		return $ret;
	}
	
	private function object2array($obj)
    {
        if (is_object($obj))
        {
        	foreach($obj->attributes() as $k=>$v)
        	{
        		if($k=='list' && count($obj->children())==1)
        		{
        			$forceList	= true;
        			break;
        		}
        	}
            $obj = get_object_vars($obj);
        }
		
        if (is_array($obj))
        {
            foreach ($obj as $key => $value)
            {
            	if($forceList && $key!='@attributes')
            	{
            		$obj[$key] = array(0=>$this->object2array($value));
            	}
            	else
            	{
            		$obj[$key] = $this->object2array($value);
            	}
            }
        }
        return $obj;
    }
}
?>